package jehc.djshi.oauth.web;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jehc.djshi.common.annotation.Auth;
import jehc.djshi.common.base.*;
import jehc.djshi.common.cache.redis.RedisUtil;
import jehc.djshi.common.constant.BaseConstant;
import jehc.djshi.common.session.HttpSessionUtils;
import jehc.djshi.common.util.JsonUtil;
import jehc.djshi.common.util.StringUtil;
import jehc.djshi.oauth.util.OauthUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
 * @Desc 授权中心在线用户API
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@RestController
@RequestMapping("/oauthOnline")
@Api(value = "授权中心在线用户API",tags = "授权中心在线用户API",description = "授权中心在线用户API")
@Slf4j
public class OauthOnlineController extends BaseAction {

    @Resource
    private HttpSessionUtils httpSessionUtils;

    @Resource
    OauthUtil oauthUtil;

    @Resource
    protected RedisUtil redisUtil;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 查询在线账户列表
     * @param baseSearch
     * @return
     */
    @ApiOperation(value="查询在线账户列表", notes="查询在线账户列表")
    @PostMapping(value="/list")
    @Auth(value = "/oauthOnline/list",authenticationType = Auth.AuthorizationType.REQUIRED_LOGIN_NOT_AUTH)
    public BasePage<List<BaseHttpSessionEntity>> getOauthKeyInfoListByCondition(@RequestBody BaseSearch baseSearch){
        long start = System.currentTimeMillis();
        RedisConnectionFactory factory =null;
        RedisConnection rc = null;
        List<String> keys = null;
        Cursor<byte[]> cursor = null;
        long tmpIndex = 0;
        try {
            ScanOptions options = ScanOptions.scanOptions().match(BaseConstant.ROOT+"Token:*").count(10000).build();//设置1次10000个
            factory = stringRedisTemplate.getConnectionFactory();
            rc = factory.getConnection();
            cursor = rc.scan(options);
            keys = new ArrayList<>();
            long startIndex = (baseSearch.getPageNo()-1) * baseSearch.getPageSize();
            long end = (baseSearch.getPageNo()) * baseSearch.getPageSize();
            while (cursor.hasNext()) {
                if (tmpIndex >= startIndex && tmpIndex < end) {
                    keys.add(new String(cursor.next()));
                    tmpIndex++;
                    continue;
                }
                //获取到满足条件的数据后,就可以退出了 如果需要拿到总数量则需要屏蔽条件（生产环境谨慎使用）
//                if(tmpIndex >=end) {
//                    break;
//                }
                tmpIndex++;
                cursor.next();
            }
        }catch (Exception e){
            log.error("分页查询Redis异常:{}",e);
        }finally {
            try {
                if(null!= cursor){
                    cursor.close();
                }
            }catch (Exception e){
                log.error("释放redis cursor异常:{}",e);
            }
            try {
                RedisConnectionUtils.releaseConnection(rc, factory);
            } catch (Exception e) {
                log.error("释放redis连接异常:{}",e);
            }
            log.info("scan扫描共耗时：{} ms key数量：{}",System.currentTimeMillis()-start,tmpIndex);
        }

        /*List<String> list  = httpSessionUtils.getAllTokenKey();*/

        List<BaseHttpSessionEntity> entityList = new ArrayList();
        String oauthAccountEntity ="";
        BaseHttpSessionEntity baseHttpSessionEntity ;
        if(!CollectionUtils.isEmpty(keys)){
            for (String token : keys ){
                oauthAccountEntity = httpSessionUtils.getAttribute(token);
                Long sessionExpire = redisUtil.getExpire(token);
                baseHttpSessionEntity  = JsonUtil.fromAliFastJson(oauthAccountEntity, BaseHttpSessionEntity.class);
                try {
                    baseHttpSessionEntity.setSessionExpire(sessionExpire);
                }catch (Exception e){
                    log.error("统计在线用户会话session有效期 异常：{}",e);
                }
                entityList.add(baseHttpSessionEntity);
            }
        }
        PageInfo<BaseHttpSessionEntity> page = new PageInfo<BaseHttpSessionEntity>(entityList);
        page.setTotal(tmpIndex);
        return outPageBootStr(page,baseSearch);
    }

    /**
     * 剔除
     * @param id
     */
    @ApiOperation(value="剔除", notes="剔除")
    @DeleteMapping(value="/delete/{id}")
    @Auth("/oauthAccount/delete")
    public BaseResult delete(@PathVariable("id")String id){
        int i = 0;
        if(!StringUtil.isEmpty(id)){
            String token = oauthUtil.getTokenByAccountId(id);
            if(!StringUtil.isEmpty(token)){
                boolean res = oauthUtil.deleteToken(token);
                if(res){
                    i = 1;
                }
            }
        }
        if(i>0){
            return outAudStr(true);
        }else{
            return outAudStr(false);
        }
    }

    /**
     * 查询在线人数
     */
    @ApiOperation(value="查询在线人数", notes="查询在线人数")
    @GetMapping(value="/count")
    @Auth(value = "/oauthOnline/count",authenticationType = Auth.AuthorizationType.REQUIRED_LOGIN_NOT_AUTH)
    public BaseResult getOnlineCount() {
        return BaseResult.success(stringRedisTemplate.opsForValue().getOperations().keys(BaseConstant.ROOT+"Token:*").size());
    }
}
